while (g_hash_table_iter_next (&hash_iter, &key, &value))
{
const char *checksum = value;
- OstreeRepoCommitState commitstate;
- GError *local_error = NULL;
-
- if (!ostree_repo_load_commit (self, checksum, NULL, &commitstate,
- error))
- goto out;
g_debug ("Finding objects to keep for commit %s", checksum);
if (!ostree_repo_traverse_commit_union (self, checksum, depth, data.reachable,
- cancellable, &local_error))
- {
- /* Don't fail traversing a partial commit */
- if ((commitstate & OSTREE_REPO_COMMIT_STATE_PARTIAL) > 0 &&
- g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
- {
- g_clear_error (&local_error);
- }
- else
- {
- g_propagate_error (error, local_error);
- goto out;
- }
- }
+ cancellable, error))
+ goto out;
}
}
GVariant *serialized_key = key;
const char *checksum;
OstreeObjectType objtype;
- OstreeRepoCommitState commitstate;
- GError *local_error = NULL;
ostree_object_name_deserialize (serialized_key, &checksum, &objtype);
if (objtype != OSTREE_OBJECT_TYPE_COMMIT)
continue;
- if (!ostree_repo_load_commit (self, checksum, NULL, &commitstate,
- error))
- goto out;
-
g_debug ("Finding objects to keep for commit %s", checksum);
if (!ostree_repo_traverse_commit_union (self, checksum, depth, data.reachable,
- cancellable, &local_error))
- {
- /* Don't fail traversing a partial commit */
- if ((commitstate & OSTREE_REPO_COMMIT_STATE_PARTIAL) > 0 &&
- g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
- {
- g_clear_error (&local_error);
- }
- else
- {
- g_propagate_error (error, local_error);
- goto out;
- }
- }
+ cancellable, error))
+ goto out;
}
}
traverse_dirtree (OstreeRepo *repo,
const char *checksum,
GHashTable *inout_reachable,
+ gboolean ignore_missing_dirs,
GCancellable *cancellable,
GError **error);
traverse_iter (OstreeRepo *repo,
OstreeRepoCommitTraverseIter *iter,
GHashTable *inout_reachable,
+ gboolean ignore_missing_dirs,
GCancellable *cancellable,
GError **error)
{
while (TRUE)
{
g_autoptr(GVariant) key = NULL;
+ g_autoptr(GError) local_error = NULL;
OstreeRepoCommitIterResult iterres =
- ostree_repo_commit_traverse_iter_next (iter, cancellable, error);
-
+ ostree_repo_commit_traverse_iter_next (iter, cancellable, &local_error);
+
if (iterres == OSTREE_REPO_COMMIT_ITER_RESULT_ERROR)
- goto out;
+ {
+ /* There is only one kind of not-found error, which is
+ failing to load the dirmeta itself, if so, we ignore that
+ (and the whole subtree) if told to. */
+ if (ignore_missing_dirs &&
+ g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
+ {
+ g_debug ("Ignoring not-found dirmeta");
+ ret = TRUE;
+ }
+ else
+ g_propagate_error (error, g_steal_pointer (&local_error));
+
+ goto out;
+ }
else if (iterres == OSTREE_REPO_COMMIT_ITER_RESULT_END)
break;
else if (iterres == OSTREE_REPO_COMMIT_ITER_RESULT_FILE)
key = NULL;
if (!traverse_dirtree (repo, content_checksum, inout_reachable,
- cancellable, error))
+ ignore_missing_dirs, cancellable, error))
goto out;
}
}
traverse_dirtree (OstreeRepo *repo,
const char *checksum,
GHashTable *inout_reachable,
+ gboolean ignore_missing_dirs,
GCancellable *cancellable,
GError **error)
{
g_autoptr(GVariant) dirtree = NULL;
ostree_cleanup_repo_commit_traverse_iter
OstreeRepoCommitTraverseIter iter = { 0, };
+ g_autoptr(GError) local_error = NULL;
if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_DIR_TREE, checksum,
- &dirtree, error))
- goto out;
+ &dirtree, &local_error))
+ {
+ if (ignore_missing_dirs &&
+ g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
+ {
+ g_print ("Ignoring not-found dirmeta %s", checksum);
+ ret = TRUE;
+ }
+ else
+ g_propagate_error (error, g_steal_pointer (&local_error));
+
+ goto out;
+ }
g_debug ("Traversing dirtree %s", checksum);
if (!ostree_repo_commit_traverse_iter_init_dirtree (&iter, repo, dirtree,
error))
goto out;
- if (!traverse_iter (repo, &iter, inout_reachable, cancellable, error))
+ if (!traverse_iter (repo, &iter, inout_reachable, ignore_missing_dirs, cancellable, error))
goto out;
ret = TRUE;
g_autoptr(GVariant) commit = NULL;
ostree_cleanup_repo_commit_traverse_iter
OstreeRepoCommitTraverseIter iter = { 0, };
+ OstreeRepoCommitState commitstate;
+ gboolean ignore_missing_dirs = FALSE;
key = ostree_object_name_serialize (commit_checksum, OSTREE_OBJECT_TYPE_COMMIT);
commit_checksum, &commit,
error))
goto out;
-
+
/* Just return if the parent isn't found; we do expect most
* people to have partial repositories.
*/
if (!commit)
break;
+ /* See if the commit is partial, if so it's not an error to lack objects */
+ if (!ostree_repo_load_commit (repo, commit_checksum, NULL, &commitstate,
+ error))
+ goto out;
+
+ if ((commitstate & OSTREE_REPO_COMMIT_STATE_PARTIAL) != 0)
+ ignore_missing_dirs = TRUE;
+
g_hash_table_add (inout_reachable, key);
key = NULL;
error))
goto out;
- if (!traverse_iter (repo, &iter, inout_reachable, cancellable, error))
+ if (!traverse_iter (repo, &iter, inout_reachable, ignore_missing_dirs, cancellable, error))
goto out;
-
+
if (maxdepth == -1 || maxdepth > 0)
{
g_free (tmp_checksum);
setup_fake_remote_repo1 "archive-z2"
-echo '1..2'
+echo '1..4'
repopath=${test_tmpdir}/ostree-srv/gnomerepo
cp -a ${repopath} ${repopath}.orig
${CMD_PREFIX} ostree --repo=repo pull origin main
assert_not_has_file repo/state/${rev}.commitpartial
${CMD_PREFIX} ostree --repo=repo fsck
-echo "ok"
+echo "ok subpaths"
+
+rm -rf repo
+
+${CMD_PREFIX} ostree --repo=repo init
+${CMD_PREFIX} ostree --repo=repo remote add --set=gpg-verify=false origin ${remoteurl}
+
+# Pull a directory which is not the first in the commit (/baz/another is before)
+${CMD_PREFIX} ostree --repo=repo pull --subpath=/baz/deeper origin main
+
+# Ensure it is there
+${CMD_PREFIX} ostree --repo=repo ls origin:main /baz/deeper
+
+# Now prune, this should not prune the /baz/deeper dirmeta even if the
+# /baz/another dirmeta is not in the repo.
+${CMD_PREFIX} ostree --repo=repo prune --refs-only
+
+# Ensure it is still there
+${CMD_PREFIX} ostree --repo=repo ls origin:main /baz/deeper
+
+echo "ok prune with commitpartial"
+
done